package com.ruoyi.system.service.impl;

import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.domain.entity.SysDocument;
import com.ruoyi.common.core.domain.entity.SysDocumentCategory;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.system.mapper.SysDocumentMapper;
import com.ruoyi.system.service.ISysDocumentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class SysDocumentServiceImpl implements ISysDocumentService {
    @Autowired
    private SysDocumentMapper documentMapper;

    @Override
    public List<SysDocument> selectDocumentList(SysDocument document) {
        return documentMapper.selectDocumentList(document);
    }

    @Override
    public SysDocument selectDocumentById(Long documentId) {
        return documentMapper.selectDocumentById(documentId);
    }

    @Override
    @Transactional
    public int insertDocument(SysDocument document) {
        document.setCreateTime(DateUtils.getNowDate());
        return documentMapper.insertDocument(document);
    }

    @Override
    @Transactional
    public int updateDocument(SysDocument document) {
        document.setUpdateTime(DateUtils.getNowDate());
        return documentMapper.updateDocument(document);
    }

    @Override
    @Transactional
    public int deleteDocumentByIds(Long[] documentIds) {
        List<String> filePathList = new ArrayList<String>();
        for (Long documentId:documentIds) {
            SysDocument document = documentMapper.selectDocumentById(documentId);
            filePathList.add(document.getFilePath().replace("/profile", RuoYiConfig.getProfile()));
        }
        int result = documentMapper.deleteDocumentByIds(documentIds);
        if(result>0){
            for (String filePath:filePathList) {

                boolean flag = FileUtils.deleteFile(filePath);
                if(!flag){
                    throw new RuntimeException("文件删除失败！");
                }
            }
        }
        return result;
    }

    @Override
    @Transactional
    public int  deleteDocumentByPath(String filePath,String fileName) {
        int result = documentMapper.deleteDocumentByPath(filePath);
        //删除fileInfo信息
        if (StringUtils.isNotEmpty(fileName)){
            documentMapper.deleteFileByName(fileName);
        }
        if(result>0){
            boolean flag = FileUtils.deleteFile(filePath.replace("/profile", RuoYiConfig.getProfile()));
            if(!flag){
                throw new RuntimeException("文件删除失败！");
            }
        }
        return result;
    }

    @Override
    public List<SysDocumentCategory> selectCategoryList(SysDocumentCategory category) {
        return documentMapper.selectCategoryList(category);
    }

    @Override
    public SysDocumentCategory selectCategoryById(Long categoryId) {
        return documentMapper.selectCategoryById(categoryId);
    }

    @Override
    @Transactional
    public int insertCategory(SysDocumentCategory category) {
        SysDocumentCategory info = documentMapper.selectCategoryById(category.getParentId());
        if (info != null) {
            category.setAncestors(info.getAncestors() + "," + category.getParentId());
        } else {
            category.setAncestors("0");
        }
        category.setCreateTime(DateUtils.getNowDate());
        return documentMapper.insertCategory(category);
    }

    @Override
    @Transactional
    public int updateCategory(SysDocumentCategory category) {
        SysDocumentCategory newParentCategory = documentMapper.selectCategoryById(category.getParentId());
        SysDocumentCategory oldCategory = documentMapper.selectCategoryById(category.getCategoryId());

        if (newParentCategory != null && oldCategory != null) {
            String newAncestors = newParentCategory.getAncestors() + "," + newParentCategory.getCategoryId();
            String oldAncestors = oldCategory.getAncestors();

            category.setAncestors(newAncestors);
            updateCategoryChildren(category.getCategoryId(), newAncestors, oldAncestors);
        }
        category.setUpdateTime(DateUtils.getNowDate());
        return documentMapper.updateCategory(category);
    }

    @Override
    @Transactional
    public int deleteCategoryById(Long categoryId) {
        return documentMapper.deleteCategoryById(categoryId);
    }

    /**
     * 修改子元素关系
     *
     * @param categoryId 被修改的分类ID
     * @param newAncestors 新的父ID集合
     * @param oldAncestors 旧的父ID集合
     */
    @Transactional
    public void updateCategoryChildren(Long categoryId, String newAncestors, String oldAncestors) {
        List<SysDocumentCategory> children = documentMapper.selectChildrenCategoryById(categoryId);
        for (SysDocumentCategory child : children) {
            child.setAncestors(child.getAncestors().replace(oldAncestors, newAncestors));
        }
        if (children.size() > 0) {
            documentMapper.updateCategoryChildren(children);
        }
    }

    /**
     * 构建前端所需要的树结构
     *
     * @param categories 分类列表
     * @return 树结构列表
     */
    public List<SysDocumentCategory> buildCategoryTree(List<SysDocumentCategory> categories) {
        List<SysDocumentCategory> returnList = new ArrayList<>();
        List<Long> tempList = categories.stream()
                .map(SysDocumentCategory::getCategoryId)
                .collect(Collectors.toList());

        for (SysDocumentCategory category : categories) {
            // 如果是顶级节点，遍历该父节点的所有子节点
            if (!tempList.contains(category.getParentId())) {
                recursionFn(categories, category);
                returnList.add(category);
            }
        }

        if (returnList.isEmpty()) {
            returnList = categories;
        }
        return returnList;
    }

    /**
     * 递归列表
     */
    private void recursionFn(List<SysDocumentCategory> list, SysDocumentCategory parent) {
        // 得到子节点列表
        List<SysDocumentCategory> childList = getChildList(list, parent);
        parent.setChildren(childList);

        for (SysDocumentCategory child : childList) {
            if (hasChild(list, child)) {
                recursionFn(list, child);
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<SysDocumentCategory> getChildList(List<SysDocumentCategory> list, SysDocumentCategory parent) {
        return list.stream()
                .filter(c -> c.getParentId() != null && c.getParentId().equals(parent.getCategoryId()))
                .collect(Collectors.toList());
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<SysDocumentCategory> list, SysDocumentCategory category) {
        return list.stream().anyMatch(c -> c.getParentId() != null && c.getParentId().equals(category.getCategoryId()));
    }

    /**
     * 判断是否存在子分类
     *
     * @param categoryId 分类ID
     * @return 结果 true存在 false不存在
     */
    public boolean hasChildByCategoryId(Long categoryId) {
        // 方法1: 使用数据库查询（适合大数据量）
        // return documentCategoryMapper.selectCountByParentId(categoryId) > 0;

        // 方法2: 使用内存中已加载的数据（适合小数据量）
        List<SysDocumentCategory> allCategories = documentMapper.selectAllCategories();
        return allCategories.stream()
                .anyMatch(c -> c.getParentId() != null && c.getParentId().equals(categoryId));
    }
}